#include "Win32LogOutput.h"

namespace my
{
	WinLogOutput::WinLogOutput()
	{
		if (AllocConsole())
		{
			m_stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);

			FILE *fDummy;
			freopen_s(&fDummy, "CONIN$", "r", stdin);
			freopen_s(&fDummy, "CONOUT$", "w", stderr);
			freopen_s(&fDummy, "CONOUT$", "w", stdout);
		}
		else
		{
			m_stdout_handle = nullptr;
		}

		m_last_attrib = 0;
	}


	void WinLogOutput::write(const char *name, LogLevel level, const char *text, size_t text_length)
	{
		std::string buf = "[";
		buf = buf + LogSystem::get_level_name(level) + "] [" + name + "] " + text + '\n';

		WORD attrib;
		switch (level)
		{
		case LogLevel::Verbose:	attrib = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; break;
		case LogLevel::Debug:	attrib = FOREGROUND_GREEN; break;
		case LogLevel::Info:	attrib = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY; break;
		case LogLevel::Warning:	attrib = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY; break;
		case LogLevel::Error:	attrib = FOREGROUND_RED | FOREGROUND_INTENSITY; break;
		case LogLevel::Fatal:	attrib = BACKGROUND_RED | BACKGROUND_INTENSITY; break;
		default:				attrib = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; break;
		}

		std::lock_guard<std::mutex> locker(m_mutex);

		OutputDebugStringA(buf.c_str());

		if (attrib != m_last_attrib)
		{
			SetConsoleTextAttribute(m_stdout_handle, attrib);
			m_last_attrib = attrib;
		}

		WriteConsoleA(m_stdout_handle, buf.c_str(), (DWORD)buf.length(), nullptr, nullptr);
	}
}
